<template>
  <div>
    <el-dialog class="custom-dialog centered-dialog" v-model="open" title="审批" width="1600px" center :close-on-click-modal="false" :modal="false">
      <div class="dialog-container">
        <!-- 左侧表单内容 -->
        <div class="form-content">
          <div class="scrollable-div">
            <MainForm ref="mainForm" :form-json="mainFormInfo.formJson" :form-data="mainFormInfo.formData" />
          </div>
          <div style="height: 300px; overflow-y: auto;">
            <el-timeline>
              <el-timeline-item v-for="(item, index) in historyRecordList" :key="index" :color="item.status === 1 ? '#0bbd87' : '#e4e7ed'">
                <HistoryNodeInfo :node-item="item" />
              </el-timeline-item>
            </el-timeline>
          </div>
          <VFormRender ref="preForm" :form-json="formJson" />
        </div>

        <!-- 右侧AI助手 -->
        <div class="ai-assistant" v-show="open">
          <div class="ai-header">
            <h3>AI助手</h3>
          </div>
          <div class="ai-chat-messages" ref="chatMessagesRef">
            <div v-for="(message, index) in chatMessages" :key="index" :class="['message', message.type]">
              <div class="message-content">
                <template v-if="message.thinking">
                  <span class="thinking-dots">{{ message.content }}</span>
                </template>
                <template v-else>
                  {{ message.content }}
                </template>
              </div>
              <div class="message-time">{{ message.time }}</div>
            </div>
          </div>
          <div class="ai-chat-input">
            <el-input
              v-model="userMessage"
              type="textarea"
              :rows="2"
              placeholder="请输入问题..."
              @keyup.enter.prevent="sendMessage"
              :disabled="isSending || isFirstAnalyzing"
            />
            <el-button 
              type="primary" 
              @click="sendMessage" 
              :loading="isSending" 
              :disabled="isSending || isFirstAnalyzing"
            >
              {{ isFirstAnalyzing ? '正在进行首次分析...' : (isSending ? '等待回答中...' : '发送') }}
            </el-button>
          </div>
        </div>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submit">审批</el-button>
          <el-button @click="open = false">取消</el-button>
          <el-button type="primary" v-if="isFirstTask" @click="modifyData">修改数据</el-button>
          <el-button type="primary" v-if="isFirstTask" @click="saveMainFormData">保存数据</el-button>
        </div>
        <el-dialog v-model="signatureDialogVisible" title="手写签名" :close-on-click-modal="false" :modal="false">
          <div>
            <div class="canvas-container">
              <canvas ref="signatureCanvas" width="800" height="300" style="border:1px solid #ccc;"></canvas>
            </div>
            <div style="margin-top: 10px;">
              <el-button type="primary" @click="saveSignature">保存签名</el-button>
              <el-button @click="clearSignature">清除签名</el-button>
            </div>
          </div>
          <template #footer>
            <div class="dialog-footer">
              <el-button @click="signatureDialogVisible = false">取消</el-button>
              <el-button type="primary" @click="confirmSignature">确定</el-button>
            </div>
          </template>
        </el-dialog>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { onMounted } from 'vue';
import { ref, reactive, toRef, nextTick, watchEffect } from "vue";
import baseService from "@/service/baseService";
import { ElMessage, ElMessageBox } from "element-plus";
import VFormRender from "@/components/FormDesigner/form-render/index.vue";
import HistoryNodeInfo from "@/components/HistoryRecord/components/HistoryNodeInfo.vue";
import MainForm from "@/components/HistoryRecord/components/MainForm.vue";
import html2canvas from 'html2canvas';
import SignaturePad from 'signature_pad';
import { ElDialog } from 'element-plus';
import axios from 'axios';
import { SortUp } from '@element-plus/icons-vue';
const signatureCanvas = ref(null);
const signaturePad = ref<SignaturePad | null>(null);
const signatureImage = ref<string | null>(null);
const signatureDialogVisible = ref(false);
import { jsPDF } from "jspdf";

// 是否打开弹出框
const open = ref(false);

// 提交表单数据
let form = toRef(
  reactive({
    processInstanceId: "",
    variables: {}
  })
);
// 提交表单数据
let MainFormData = toRef(
  reactive({
    businessKey: "",
    formId: "",
    formName: "",
    formJson: {},
    definitionId: "",
    definitionName: ""
  })
);
//表单头
const analysisParams = ref<any>({});
// 动态表单实例
const preForm = ref();
const mainForm = ref();
const historyRecordList = ref<any[]>([]);
// 动态表单结构数据
const formJson = ref<object>({});
const mainFormInfo = ref<any>({});
  historyRecordList.value = [];
// 当前节点id
let activityId = "";
// 新增一个属性来存储是否是第一个任务，初始为false
const isFirstTask = ref(false);
// 使用 reactive 来创建一个响应式的引用
const state = reactive({
  taskIdkey: '', // 默认为空字符串或其他初始值
  instanceId: '',
  businessKey: '',
  // 可以在这里添加其他需要在组件内共享的状态
});
// AI对话相关的状态
const aiDialogVisible = ref(true); // 默认显示AI对话框
const chatMessages = ref<Array<{type: string, content: string, time: string}>>([]);
const userMessage = ref('');
const isSending = ref(false);
const chatMessagesRef = ref<HTMLElement | null>(null);

// 添加思考状态
const isThinking = ref(false);

// 添加首次分析状态
const isFirstAnalyzing = ref(false);

// 格式化时间函数
const formatTime = () => {
  const now = new Date();
  return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;
};

// 修改发送消息函数
const sendMessage = async () => {
  if (!userMessage.value.trim() || isSending.value) return;
  
  const messageContent = userMessage.value;
  userMessage.value = '';
  isSending.value = true;
  isThinking.value = true; // 显示思考状态

  // 添加用户消息到界面
  chatMessages.value.push({
    type: 'user',
    content: messageContent,
    time: formatTime()
  });

  // 添加思考中的消息
  chatMessages.value.push({
    type: 'ai',
    content: '思考中...',
    time: formatTime(),
    thinking: true // 标记为思考状态
  });

  try {
    const response = await baseService.post('/deepSeek/Analysis', {
      analysisParams: analysisParams.value,
      query: messageContent
    });

    // 移除思考中的消息
    chatMessages.value = chatMessages.value.filter(msg => !msg.thinking);

    if (response.code === 200) {
      chatMessages.value.push({
        type: 'ai',
        content: response.data,
        time: formatTime()
      });
    } else {
      chatMessages.value.push({
        type: 'ai',
        content: '抱歉，我暂时无法回答您的问题。',
        time: formatTime()
      });
    }
  } catch (error) {
    console.error('AI对话请求失败:', error);
    // 移除思考中的消息
    chatMessages.value = chatMessages.value.filter(msg => !msg.thinking);
    
    chatMessages.value.push({
      type: 'ai',
      content: '网络错误，请稍后重试。',
      time: formatTime()
    });
  } finally {
    isSending.value = false;
    isThinking.value = false;
    // 滚动到最新消息
    nextTick(() => {
      if (chatMessagesRef.value) {
        chatMessagesRef.value.scrollTop = chatMessagesRef.value.scrollHeight;
      }
    });
  }
};

/**
 * 初始化
 * @param instanceId 流程实例id
 * @param taskId 任务id
 * @param taskDefinitionKey 节点id
 */
const handleOpen = async (instanceId: string, taskId: string, taskDefinitionKey: string) => {
  form.value.processInstanceId = instanceId;
  state.taskIdkey = taskId;
  state.instanceId = instanceId;
  activityId = taskDefinitionKey;

  try {
    // 获取主表单信息
    const mainFormResponse = await baseService.get(`/processStart/getMainFormInfo?instanceId=${instanceId}`);
    if (mainFormResponse.code === 200 && mainFormResponse.data !== "") {
      mainFormInfo.value = mainFormResponse.data;
      // 获取分析所需参数
      analysisParams.value = mainFormInfo.value.formJson.widgetList[0].options.textContent;
      
      // 初始化其他数据
      open.value = true;
    }
  } catch (error) {
    console.error('获取表单数据失败:', error);
    ElMessage.error('获取表单数据失败');
  }

  // 获取动态表单
  baseService.get(`/processTodo/getNodeForm/${taskId}`).then((res) => {
    if (res.code === 200 && res.data !== "") {
      formJson.value = res.data;
      // 打印转换后的字符串
      open.value = true;
      nextTick(() => {
        if (Object.keys(res.data).length !== 0) {
          preForm.value?.setFormJson(res.data);
        }
      });
    }
  });/*  */

  baseService.get(`/processStart/getHistoryRecord?instanceId=${instanceId}`).then((res) => {
    if (res.code === 200 && res.data !== "") {
      historyRecordList.value = res.data;
      open.value = true;
      // nextTick(() => {
      //   if (Object.keys(res.data).length !== 0) {
      //     historyRecordList.value?.resetForm();
      //     historyRecordList.value?.setFormJson(res.data);
      //   }
      // });
    }
  });/*  */
 isFirstApproveTask();
  // 确保在获取到数据后初始化AI助手
  await initAiAssistant();

};

/**
 * 提交
 */
async function submit() {
  // 获取动态表单数据
  const formData = await preForm.value.getFormData();

  ElMessageBox.confirm("是否要提交?", "提示").then(() => {
    // 在流程节点局部变量设置值, 可以方便使用 `${}` 直接设置流程变量
    var variables = JSON.parse(JSON.stringify(formData));

    // 在流程节点局部变量设置表单的结构和值方便以后回显使用
    variables[`${activityId}_formJson`] = formJson;
    variables[`${activityId}_formData`] = JSON.parse(JSON.stringify(formData));
    form.value.variables = variables;

    baseService.post(`/processTodo/complete`, form.value).then((res) => {
      if (res.code === 200) {
        ElMessage.success(res.msg);
        open.value = false;
        emit("ok");
      } else {
        ElMessage.error(res.msg);
      }
    });
  });
}

const emit = defineEmits<{
  (event: "ok"): void;
}>();

defineExpose({
  handleOpen
});

async function exportToPDF() {
    try {
        const mainFormElement = document.querySelector('.scrollable-div') as HTMLElement;
        if (!mainFormElement) {
            console.error('Main form element not found');
            return;
        }

        // 等待 1 秒，确保滚动完成
        await new Promise<void>((resolve) => {
            requestAnimationFrame(() => {
                // 直接设置目标 div 的滚动位置到顶部
                const scrollableDiv = document.querySelector('.scrollable-div') as HTMLElement;
                if (scrollableDiv) {
                    scrollableDiv.scrollTop = 0;
                }
                setTimeout(() => {
                    resolve(undefined); // 传递 undefined
                }, 1000);
            });
        });

        console.log('开始捕获页面元素为图像...');
        // 此时滚动已经完成，可以安全地执行 html2canvas
        const canvas = await html2canvas(mainFormElement, {
            scale: 2, // 保持较高的清晰度
            allowTaint: true,
            useCORS: true, // 跨域图像
        });
        const imgData = canvas.toDataURL('image/jpeg', 1.0);
        const imgProps = new Image();
        imgProps.src = imgData;

        console.log('创建 PDF 文档...');
        // 创建 PDF 文档
        const pdf = new jsPDF({
            orientation: 'p', // 纵向
            unit: 'mm', // 单位为毫米
            format: 'a4', // A4 纸大小
        });

        console.log('等待主表单图片加载...');
        // 等待图片加载
        await new Promise((resolve, reject) => {
            imgProps.onload = () => {
                console.log('主表单图片加载完成。');
                // 添加主表单内容
                const scaleFactor = pdf.internal.pageSize.getWidth() / imgProps.width;
                const imgWidth = pdf.internal.pageSize.getWidth() - 20; // 减少一些宽度以添加边距
                const imgHeight = (imgProps.height * pdf.internal.pageSize.getWidth()) / imgProps.width;
                const imgPosX = 10; // 添加一些左边缘距
                pdf.addImage(imgData, 'JPEG', imgPosX, 10, imgWidth, imgHeight);

                // 添加签名图片
                if (signatureImage.value) {
                    const signatureImg = new Image();
                    signatureImg.src = signatureImage.value;
                    signatureImg.onload = () => {
                        const signScaleFactor = 70 / signatureImg.width; // 设定签名图片宽度为 70mm
                        const signWidth = 70;
                        const signHeight = signatureImg.height * signScaleFactor;
                        const signPosX = pdf.internal.pageSize.getWidth() - signWidth - 10; // 设置签名图片靠右对齐
                        const signPosY = pdf.internal.pageSize.getHeight() - signHeight - 20; // 设置签名图片靠下对齐，并增加一些底部边距
                        pdf.addImage(signatureImg.src, 'JPEG', signPosX, signPosY, signWidth, signHeight);
                        resolve(undefined); // 传递 undefined
                    };
                    signatureImg.onerror = (error) => {
                        console.error('Signature image loading error:', error);
                        reject(error);
                    };
                } else {
                    resolve(undefined); // 传递 undefined
                }
            };

            imgProps.onerror = (error) => {
                console.error('Main form image loading error:', error);
                reject(error);
            };
        });

        // 保存 PDF
        console.log('保存 PDF...');
        pdf.save('审批单.pdf');
        open.value = false;
    } catch (error) {
        console.error('Error while exporting to PDF:', error);
    }
}

function initSignaturePad() {
  if (signatureCanvas.value) {
    signaturePad.value = new SignaturePad(signatureCanvas.value, { backgroundColor: 'rgba(255, 255, 255, 0)' });
  }
}

function openSignatureDialog() {
  signatureDialogVisible.value = true;
  nextTick(() => {
    initSignaturePad();
  });
}

async function saveSignature() {
  if (signaturePad.value && !signaturePad.value.isEmpty()) {
    // 将签名转换为DataURL
    const signatureDataUrl = signaturePad.value.toDataURL();
    // 将签名保存到组件状态中
    signatureImage.value = signatureDataUrl;
    let cacheTokenString = localStorage.getItem('CacheToken');

if (cacheTokenString) {
  // 将获取到的字符串转换成JavaScript对象
  let cacheTokenObject = JSON.parse(cacheTokenString);

  // 确保转换后的对象包含我们需要的属性
  if (cacheTokenObject && typeof cacheTokenObject === 'object') {
    // 从对象中获取'account'属性的值
    var accountName = cacheTokenObject.account;

    // 打印或使用获取到的'account'值
    console.log('Account name:', accountName);
  } else {
    console.error('The retrieved data is not in the expected format.');
  }
} else {
  console.error('No data found with the key \'CacheToken\'.');
}
    try {
      // 使用baseService发送POST请求到后端
      const response = await baseService.post('/save-signature', {
        signature: signatureDataUrl,
        account: accountName
      });
      // 检查响应状态码
      if (response.code === 200) {
        ElMessage.success('签名已保存并成功发送到服务器');
        signatureDialogVisible.value = false;
      } else {
        ElMessage.error('签名保存成功，但发送到服务器失败');
      }
    } catch (error) {
      console.error('签名发送请求失败:', error);
      ElMessage.error('签名保存成功，但发送时发生错误');
    }
  } else {
    ElMessage.warning('请先签名');
  }
}
function clearSignature() {
  if (signaturePad.value) {
    signaturePad.value.clear();
    signatureImage.value = null;
  }
}

function confirmSignature() {
  // 这里可以添加将签名图片保存到数据库或其他逻辑
  saveSignature();
  signatureDialogVisible.value = false;
}

// 监听对话框的显示状态，初始化签名板
watchEffect(() => {
  if (signatureDialogVisible.value) {
    initSignaturePad();
  }
});
const getSignatureByAccount = async (accountName) => {
  try {
    // 使用GET请求，并将账户名作为查询参数
    const response = await baseService.get(`/get-by-account/${accountName}`);

    // 处理响应数据
    if (response.code === 200) {
      // 假设响应数据中包含签名图像信息
      const signatureImage = response.data;  // 根据需要处理签名图像信息，例如显示或进一步处理
      return signatureImage;
    } else {
      ElMessage.error("获取签名图像失败");
    }
  } catch (error) {
    console.error('请求签名图像时发生错误:', error);
    ElMessage.error("请求签名图像时发生错误");
  }
};
const modifyData = async () => {  
  try {  
    const response = await baseService.get(`/task/${state.taskIdkey}/isFirst`);  
    if (response.code === 200) {  
      isFirstTask.value = response.data; // 这里 response.data 将会是 true 或 false  
      if (isFirstTask.value) {  
        mainForm.value?.enableForm(); // 如果是第一个任务，将主表单设置为可编辑状态  
      } else {  
        // 如果不是第一个任务，这里可以添加其他逻辑  
      }  
    } else {  
      ElMessage.error(response.msg);  
    }  
  } catch (error) {  
    console.error('Error while checking if it is the first task:', error);  
    ElMessage.error('检查是否为第一个任务时发生错误');  
  }  
}
const isFirstApproveTask = async () => {  
  try {  
    const response = await baseService.get(`/task/${state.taskIdkey}/isFirst`);  
    if (response.code === 200) {  
      isFirstTask.value = response.data; // 这里 response.data 将会是 true 或 false  
    } else {  
      ElMessage.error(response.msg);  
    }  
  } catch (error) {  
    console.error('Error while checking if it is the first task:', error);  
    ElMessage.error('检查是否为第一个任务时发生错误');  
  }  
}
const saveMainFormData = async () => {
  try {
    const formDataPromise = mainForm.value?.getUpdatedFormData();   
  // 然后获取表单数据，这里 getUpdatedFormData 应该返回一个 Promise
    if (!formDataPromise) {
      throw new Error('无法获取表单数据');
    }
    const formJson = mainForm.value?.getFormStructure();   
  // 然后获取表单数据，这里 getUpdatedFormData 应该返回一个 Promise
    if (!formJson) {
      throw new Error('无法获取表单结构');
    }

    // 等待表单数据获取完成
    const formData = await formDataPromise;
    console.log('获取到的 MainForm 数据:', formData);
    const taskId = state.taskIdkey; // 从 state 获取 taskKey
    const businessKey = await getBusinessKey(taskId);
    console.log("获取到的业务key:", businessKey);
        // 真实要提交的数据
        const subForm = {
    businessKey: state.businessKey,
    instanceId: state.instanceId,
    variables: {}
    };
    // 设置流程变量
    subForm.variables = JSON.parse(JSON.stringify(formData));
    subForm.variables[`${state.businessKey}_formData`] = JSON.parse(JSON.stringify(formData));
    subForm.variables[`${state.businessKey}_formJson`] = formJson;
    mainForm.value?.setFormJsonInChildComponent(formJson);  
    // // 提交数据
    baseService.post(`/processStart/saveMainFrom`, subForm).then((res) => {
      if (res.code === 200) {
        ElMessage.success(res.msg);
        open.value = false;
        emit("ok");
      } else {
        ElMessage.error(res.msg);
      }
    });
  } catch (error) {
    console.error('获取 MainForm 数据时发生错误:', error);
    // 可以在这里添加错误处理逻辑，例如显示错误消息
    ElMessage.error('保存数据时发生错误');
  }
};

async function getBusinessKey(taskId: string): Promise<string> {
  try {
    const response = await baseService.get(`/${taskId}/businessKey`);

    if (typeof response.data === 'string') {
      const businessKey = response.data;

      if (businessKey !== null && businessKey !== undefined) {
        state.businessKey = businessKey;
      } else {
        // You can choose a default value
        state.businessKey = 'default-business-key';
        // Or throw an exception
        // throw new Error('Business key cannot be null or undefined');
      }

      return state.businessKey;
    } else {
      console.error("请求失败，响应不是字符串：", response);
      return 'default-business-key'; // Return a default value in case of error
    }
  } catch (error) {
    // Explicitly type error as Error
    if (error instanceof Error) {
      console.error("请求出错：", error);
      console.error("错误堆栈跟踪：", error.stack);
    } else {
      console.error("未知错误：", error);
    }
    return 'default-business-key'; // Return a default value in case of error
  }
}

// 修改初始化AI助手函数
const initAiAssistant = async () => {
  try {
    isFirstAnalyzing.value = true; // 开始首次分析
    
    // 显示初始化消息
    chatMessages.value = [{
      type: 'ai',
      content: '您好，我是您的AI助手。我正在分析当前表单...',
      time: formatTime(),
      thinking: true
    }];

    console.log('开始AI分析，参数:', analysisParams.value);
    
    // 调用首次分析接口
    const response = await baseService.post('/deepSeek/firstAnalysis', {
      analysisParams: analysisParams.value
    });

    // 移除思考中的消息
    chatMessages.value = chatMessages.value.filter(msg => !msg.thinking);

    if (response.code === 200) {
      chatMessages.value.push({
        type: 'ai',
        content: response.data,
        time: formatTime()
      });
    } else {
      chatMessages.value.push({
        type: 'ai',
        content: '抱歉，分析过程中出现错误，请稍后重试。',
        time: formatTime()
      });
    }
  } catch (error) {
    console.error('AI首次分析失败:', error);
    // 移除思考中的消息
    chatMessages.value = chatMessages.value.filter(msg => !msg.thinking);
    
    chatMessages.value.push({
      type: 'ai',
      content: '网络错误，无法完成分析。',
      time: formatTime()
    });
  } finally {
    isFirstAnalyzing.value = false; // 首次分析完成
  }
};

onMounted(() => {
});

</script>

<style scoped>
.scrollable-div {
  max-height: 500px; /* 根据需要设置最大高度 */
  overflow-y: auto;
}
.dialog-footer {
  display: flex;
  justify-content: center;
}
.centered-dialog {
  /* 确保对话框居中且自适应内容高度，直到达到80vh的最大高度 */
  margin-top: 5vh;
  max-height: 90vh; /* 80%的视口高度，可根据实际情况调整 */
  overflow-y: auto;
}
/* 添加到你的样式文件中 */
.canvas-container {
    text-align: center; /* 使用text-align居中 */
    padding: 20px; /* 根据需要调整内边距 */
  }
.main-form-white-bg {
  background-color: white;
}
.main-form-white-bg input {
  background-color: white;
}

/* 新增和修改的样式 */
.dialog-container {
  display: flex;
  gap: 20px;
  height: calc(100vh - 300px);
  min-height: 600px;
}

.form-content {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.ai-assistant {
  width: 350px;
  border-left: 1px solid #e0e0e0;
  display: flex;
  flex-direction: column;
  background-color: #f9f9f9;
  border-radius: 4px;
}

.ai-header {
  padding: 10px 15px;
  border-bottom: 1px solid #e0e0e0;
  background-color: #f0f0f0;
}

.ai-header h3 {
  margin: 0;
  font-size: 16px;
  color: #333;
}

.ai-chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
}

.message {
  margin-bottom: 10px;
  padding: 8px 12px;
  border-radius: 8px;
  max-width: 85%;
}

.message.user {
  background-color: #e1f3fb;
  margin-left: auto;
}

.message.ai {
  background-color: #f0f0f0;
  margin-right: auto;
}

.message-content {
  word-break: break-word;
  font-size: 14px;
}

.message-time {
  font-size: 12px;
  color: #999;
  text-align: right;
  margin-top: 4px;
}

.ai-chat-input {
  padding: 10px;
  border-top: 1px solid #e0e0e0;
  background-color: #fff;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* 修改主对话框样式 */
:deep(.custom-dialog) {
  max-width: 1600px !important;
}

:deep(.el-dialog__body) {
  padding: 10px 20px;
}

.scrollable-div {
  max-height: none;
  flex: 1;
  overflow-y: auto;
}

/* 在style中添加思考动画样式 */
.thinking-dots::after {
  content: '';
  animation: thinking 1.5s infinite;
}

@keyframes thinking {
  0% { content: ''; }
  25% { content: '.'; }
  50% { content: '..'; }
  75% { content: '...'; }
  100% { content: ''; }
}

/* 修改AI消息样式 */
.message.ai {
  background-color: #f0f0f0;
  margin-right: auto;
}

.message.ai.thinking {
  background-color: #e8e8e8;
  opacity: 0.8;
}
</style>

